<?php
/**
 * 队列消费日志
 */
namespace App\Models\MainDB\Queue;

use Illuminate\Database\Eloquent\Model;

class QueueLog extends Model{

    protected $table = 'ln_queue_log';
//    protected $fillable = [
//        'id',
//        'out_key',
//        'content',
//        'job_name',
//        'queue_name',
//        'uni_key',
//        'send_status',
//        'retry_num',
//        'open_at',
//    ];
    public $timestamps = false;

    const SENDING_TO_QUEUE = 1; //等待发送至队列（已入库不确定是否发送到队列成功与否）
    const WAITING_CONSUME  = 2;  //待消费
    const CONSUME_SUCCESS  = 3;  //消费成功
    const CONSUME_FAIL = 4;  //消费失败(超过5次)
    const DATA_ERROR = 5;  //数据错误
    const CONSUME_FAIL_PROCESS = 6;  //数据错误（未超过5次）

    /**
     * 记录队列发送日志
     * @param $jobName string job名称
     * @param $originData mixed 原始数据
     * @param int $delayTime 延时时间
     * @param string $outKey 外键
     * @param int $status 状态
     * @return false|array
     */
    public function addQueueData($jobName, $originData, $delayTime=0,$outKey = '',$status=self::SENDING_TO_QUEUE)
    {
        mt_srand();
        $uniKey = md5(uniqid() . '_' . mt_rand(1000, 9999) . ((int)(microtime(true) * 1000)));
        $jobData = [
            'queue_data' =>   $originData,
            'queue_uni_key' =>   $uniKey,
            'queue_send_time' => time()+$delayTime,
            'retry_num' =>   0,
        ];
        $dbData = [
            'out_key'     => $outKey,
            'content' => json_encode($jobData),
            'job_name'    => $jobName,
            'uni_key'        => $uniKey,
            'send_status' => $status,
            'retry_num'   => 0,
        ];
        if(!empty($delayTime) && $delayTime>0){ //延时消息需要维护消息最先消费时间字段
            $dbData['open_at'] = date('Y-m-d H:i:s',time()+$delayTime);
        }
        $res = $this->insert($dbData);
        if (!$res) {
            return false;
        } else {
            return $jobData;
        }
    }

    /**
     * 批量增加队列待投递数据
     * @param array $originData
     * @return array|false
     */
    public function pitAddQueueData(array $originData)
    {
        $dbData = $uniKeys = [];
        foreach ($originData as $v) {
            if(empty($v['job_name'])){
                continue;
            }
            mt_srand();
            $uniKey = md5(uniqid() . '_' . mt_rand(1000, 9999) . ((int)(microtime(true) * 1000)));
            $dbData[] = [
                'out_key'     => $v['out_key'] ?? '',
                'content' => json_encode($v['content'] ?? ''),
                'job_name'    => $v['job_name'],
                'queue_name'    => $v['queue_name']??'',
                'uni_key'     => empty($v['uni_key'])?$uniKey:$v['uni_key'],
                'send_status' => $v['send_status']?? self::SENDING_TO_QUEUE,
                'retry_num'   => 0,
            ];
            $uniKeys[] = $uniKey;
        }
        $res = $this->insert($dbData);
        if (!$res) {
            return false;
        } else {
            return $uniKeys;
        }
    }

    /**
     * 更新数据状态为待消费
     * @param $uniKey string|array 唯一消费标识
     * @return mixed
     */
    public function updateDataToWaitingConsume($uniKey){
        if(empty($uniKey)){
            return true;
        }
        if(is_array($uniKey)){
            return $this->where([
                'uni_key' => [$uniKey, 'in'],
                'send_status' => self::SENDING_TO_QUEUE,
            ])->update( ['send_status' => self::WAITING_CONSUME]);
        }else{
            return $this->where([
                'uni_key' => $uniKey,
                'send_status' => self::SENDING_TO_QUEUE,
            ])->update(['send_status' => self::WAITING_CONSUME]);
        }
    }
    /**
     * 更新数据为消费成功
     * @param $uniKey string|array 唯一消费标识
     * @return mixed
     */
    public function updateDataToConsumeSuccess($uniKey){
        if(empty($uniKey)){
            return true;
        }
        try {
            if(is_array($uniKey)){
                return $this->where([
                    'uni_key' => [$uniKey, 'in'],
                ])->update( ['send_status' => self::CONSUME_SUCCESS]);
            }else{
                return $this->where([
                    'uni_key' => $uniKey,
                ])->update(['send_status' => self::CONSUME_SUCCESS]);
            }
        }catch (\Exception $e){
            return  false;
        }
    }
    /**
     * 更新数据为中途消费失败
     * @param $uniKey string|array 唯一消费标识
     * @return mixed
     */
    public function updateDataToProcessHandelError($uniKey){
        if(empty($uniKey)){
            return true;
        }
        if(is_array($uniKey)){
            return $this->where([
                'uni_key' => [$uniKey, 'in'],
            ])->update( ['send_status' => self::CONSUME_FAIL_PROCESS]);
        }else{
            return $this->where([
                'uni_key' => $uniKey,
            ])->update(['send_status' => self::CONSUME_FAIL_PROCESS]);
        }
    }
}